package me.lwn.auth.security.web.authentication;

import com.fasterxml.jackson.databind.ObjectMapper;
import me.lwn.auth.common.HttpMsg;
import me.lwn.auth.security.utils.VerificationCodeImgUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.security.web.util.matcher.AndRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 验证码获取过滤器
 *
 * @author lizhichao
 * @since 0.0.1
 */
public final class CaptchaEndpointFilter extends OncePerRequestFilter {

    private static final String DEFAULT_CAPTCHA_ENDPOINT_URI = "/oauth2/captcha";

    private final RequestMatcher captchaMatcher;

    public CaptchaEndpointFilter() {
        this(DEFAULT_CAPTCHA_ENDPOINT_URI);
    }

    public CaptchaEndpointFilter(String captchaUri) {
        this.captchaMatcher = createDefaultRequestMatcher(captchaUri);
    }

    private static RequestMatcher createDefaultRequestMatcher(String captchaUri) {
        RequestMatcher authorizationRequestGetMatcher = new AntPathRequestMatcher(
                captchaUri, HttpMethod.GET.name());
        RequestMatcher authorizationRequestPostMatcher = new AntPathRequestMatcher(
                captchaUri, HttpMethod.POST.name());

        return new OrRequestMatcher(
                authorizationRequestGetMatcher,
                new AndRequestMatcher(
                        authorizationRequestPostMatcher));
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

        if (!this.captchaMatcher.matches(request)) {
            filterChain.doFilter(request, response);
            return;
        }

        VerificationCodeImgUtils code = new VerificationCodeImgUtils(150, 50, 4, 50);
        request.getSession().setAttribute("code", code.getCode());
        String base64Image = code.base64ImageCode();
        response.setHeader(HttpHeaders.PRAGMA, "no-cache");
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
        response.setDateHeader(HttpHeaders.EXPIRES, 0);
        HttpMsg<String> res = HttpMsg.success();
        res.setData(base64Image);
        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(res));
    }
}
